﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Web;
using System.Windows.Threading;

namespace Common
{
    public static class Downloader
    {
        public static event DownloadEvent DownloadProgressChangedHander;
        private static Dispatcher _dispatcher = null;
        public static void SetDispatcher(Dispatcher dispatcher)
        {
            _dispatcher = dispatcher;
        }

        public static void OnDownloadProgressChangedHander(object sender, DownloadEventArgs e)
        {
            DownloadEvent handler = DownloadProgressChangedHander;
            if (handler != null) handler(sender, e);
        }

        public static DownloadResult Download(EshubaBook book)
        {
            if (book == null) return DownloadResult.InvalidFile;
            if (string.IsNullOrEmpty(book.DownloadUrl)) return DownloadResult.InvalidFile;
            HttpWebResponse response = null;
            Stream rStream = null;
            FileStream fs = null;
            try
            {
                response = HttpTool.GetResponse(book.DownloadUrl, Encoding.Default, HttpMethods.Get);
                if (response == null) return DownloadResult.SourceRemoved;
                var uriList = HttpUtility.UrlDecode(response.ResponseUri.AbsolutePath, Encoding.Default).Split(new[] { '/' }).ToList();
                uriList.Reverse();
                book.Name = uriList[0];
                rStream = response.GetResponseStream();
                if (rStream == null) return DownloadResult.SourceRemoved;
                string path = Settings.Instance.StorageDirectory + book.GetRelativePath();
                string dir = Path.GetDirectoryName(path);
                if (dir != null && !Directory.Exists(dir)) Directory.CreateDirectory(dir);
                fs = new FileStream(path, FileMode.Create);
                long bookLength = response.ContentLength;
                long receiveLength = 0;
                const int bufferLength = 8 * 1024;
                byte[] buffer = new byte[bookLength];
                int readSize = rStream.Read(buffer, 0, bufferLength);
                DateTime lastTime = DateTime.Now;
                int alertCount = 0;
                while (readSize > 0)
                {
                    receiveLength += readSize;
                    fs.Write(buffer, 0, readSize);
                    ++alertCount;
                    if (alertCount >= 10)
                    {
                        Thread.Sleep(1);
                        alertCount = 0;
                    }
                    if ((DateTime.Now - lastTime).TotalMilliseconds > 500)
                        OnDownloadProgressChangedHander(book, new DownloadEventArgs(DownloadResult.Ok, receiveLength, bookLength));
                    readSize = rStream.Read(buffer, 0, bufferLength);
                }
                return DownloadResult.Success;
            }
            finally
            {
                if (response != null) response.Close();
                if (rStream != null) rStream.Close();
                if (fs != null) fs.Close();
            }
        }
    }
}
